home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 August (Alt) / CHIP 2005-08.1.iso / program / guvenlik / syslinux-3.07.exe / com32.inc < prev    next >
Encoding:
Text File  |  2005-01-06  |  8.0 KB  |  360 lines

  1. ;; $Id: com32.inc,v 1.9 2005/01/06 22:34:06 hpa Exp $
  2. ;; -----------------------------------------------------------------------
  3. ;;   
  4. ;;   Copyright 1994-2003 H. Peter Anvin - All Rights Reserved
  5. ;;
  6. ;;   This program is free software; you can redistribute it and/or modify
  7. ;;   it under the terms of the GNU General Public License as published by
  8. ;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
  9. ;;   Boston MA 02111-1307, USA; either version 2 of the License, or
  10. ;;   (at your option) any later version; incorporated herein by reference.
  11. ;;
  12. ;; -----------------------------------------------------------------------
  13.  
  14. ;;
  15. ;; com32.inc
  16. ;;
  17. ;; Common code for running a COM32 image
  18. ;;
  19.  
  20. ;
  21. ; Load a COM32 image.  A COM32 image is the 32-bit analogue to a DOS
  22. ; .com file.  A COM32 image is loaded at address 0x101000, with %esp
  23. ; set to the high end of usable memory.
  24. ;
  25. ; A COM32 image should begin with the magic bytes:
  26. ; B8 FF 4C CD 21, which is "mov eax,0x21cd4cff" in 32-bit mode and
  27. ; "mov ax,0x4cff; int 0x21" in 16-bit mode.  This will abort the
  28. ; program with an error if run in 16-bit mode.
  29. ;
  30. pm_idt:        equ 0x100000
  31. pm_entry:    equ 0x101000
  32.  
  33.         bits 16
  34.         section .data
  35.         align 2, db 0
  36. com32_pmidt:
  37.         dw 8*256        ; Limit
  38.         dd pm_idt        ; Address
  39.  
  40. com32_rmidt:
  41.         dw 0ffffh        ; Limit
  42.         dd 0            ; Address
  43.  
  44.         section .text
  45. is_com32_image:
  46.         push si            ; Save file handle
  47.         push dx            ; File length held in DX:AX
  48.         push ax
  49.  
  50.         call make_plain_cmdline
  51.         ; Copy the command line into the low cmdline buffer
  52.         mov ax,real_mode_seg
  53.         mov fs,ax
  54.         mov si,cmd_line_here
  55.         mov di,command_line
  56.         mov cx,[CmdLinePtr]
  57.         inc cx            ; Include final null
  58.         sub cx,si
  59.         fs rep movsb
  60.  
  61.         call highmemsize    ; We need the high memory size...
  62.         call comboot_setup_api    ; Set up the COMBOOT-style API
  63.  
  64.         mov edi,pm_entry    ; Load address
  65.         pop eax            ; File length
  66.         pop si            ; File handle
  67.         xor dx,dx        ; No padding
  68.         call load_high
  69.         call crlf
  70.  
  71. com32_start:
  72.         mov ebx,com32_call_start    ; Where to go in PM
  73.  
  74. com32_enter_pm:
  75.         cli
  76.         mov ax,cs
  77.         mov ds,ax
  78.         mov [SavedSSSP],sp
  79.         mov [SavedSSSP+2],ss
  80.         cld
  81.         call a20_test
  82.         jnz .a20ok
  83.         call enable_a20
  84.  
  85. .a20ok:
  86.         lgdt [bcopy_gdt]    ; We can use the same GDT just fine
  87.         lidt [com32_pmidt]    ; Set up the IDT
  88.         mov eax,cr0
  89.         or al,1
  90.         mov cr0,eax        ; Enter protected mode
  91.         jmp 20h:.in_pm
  92.         
  93.         bits 32
  94. .in_pm:
  95.         xor eax,eax        ; Available for future use...
  96.         mov fs,eax
  97.         mov gs,eax
  98.  
  99.         mov al,28h        ; Set up data segments
  100.         mov es,eax
  101.         mov ds,eax
  102.         mov ss,eax
  103.  
  104.         mov esp,[PMESP]        ; Load protmode %esp if available
  105.         jmp ebx            ; Go to where we need to go
  106.  
  107. ;
  108. ; This is invoked right before the actually starting the COM32
  109. ; progam, in 32-bit mode...
  110. ;
  111. com32_call_start:
  112.         ;
  113.         ; Point the stack to the end of high memory
  114.         ;
  115.         mov esp,[word HighMemSize]
  116.  
  117.         ;
  118.         ; Set up the protmode IDT and the interrupt jump buffers
  119.         ; We set these up in the system area at 0x100000,
  120.         ; but we could also put them beyond the stack.
  121.         ;
  122.         mov edi,pm_idt
  123.  
  124.         ; Form an interrupt gate descriptor
  125.         mov eax,0x00200000+((pm_idt+8*256)&0x0000ffff)
  126.         mov ebx,0x0000ee00+((pm_idt+8*256)&0xffff0000)
  127.         xor ecx,ecx
  128.         inc ch                ; ecx <- 256
  129.  
  130.         push ecx
  131. .make_idt:
  132.         stosd
  133.         add eax,8
  134.         xchg eax,ebx
  135.         stosd
  136.         xchg eax,ebx
  137.         loop .make_idt
  138.  
  139.         pop ecx
  140.  
  141.         ; Each entry in the interrupt jump buffer contains
  142.         ; the following instructions:
  143.         ;
  144.         ; 00000000 60                pushad
  145.         ; 00000001 B0xx              mov al,<interrupt#>
  146.         ; 00000003 E9xxxxxxxx        jmp com32_handle_interrupt
  147.  
  148.         mov eax,0e900b060h
  149.         mov ebx,com32_handle_interrupt-(pm_idt+8*256+8)
  150.  
  151. .make_ijb:
  152.         stosd
  153.         sub [edi-2],cl            ; Interrupt #
  154.         xchg eax,ebx
  155.         stosd
  156.         sub eax,8
  157.         xchg eax,ebx
  158.         loop .make_ijb
  159.  
  160.         ; Now everything is set up for interrupts...
  161.  
  162.         push dword com32_farcall    ; Farcall entry point
  163.         push dword (1 << 16)        ; 64K bounce buffer
  164.         push dword (comboot_seg << 4)    ; Bounce buffer address
  165.         push dword com32_intcall    ; Intcall entry point
  166.         push dword command_line        ; Command line pointer
  167.         push dword 5            ; Argument count
  168.         sti                ; Interrupts OK now
  169.         call pm_entry            ; Run the program...
  170.         ; ... on return, fall through to com32_exit ...
  171.  
  172. com32_exit:
  173.         mov bx,com32_done    ; Return to command loop
  174.  
  175. com32_enter_rm:
  176.         cli
  177.         cld
  178.         mov [PMESP],esp        ; Save exit %esp
  179.         xor esp,esp        ; Make sure the high bits are zero
  180.         jmp 08h:.in_pm16    ; Return to 16-bit mode first
  181.  
  182.         bits 16
  183. .in_pm16:
  184.         mov ax,18h        ; Real-mode-like segment
  185.         mov es,ax
  186.         mov ds,ax
  187.         mov ss,ax
  188.         mov fs,ax
  189.         mov gs,ax
  190.  
  191.         lidt [com32_rmidt]    ; Real-mode IDT (rm needs no GDT)
  192.         mov eax,cr0
  193.         and al,~1
  194.         mov cr0,eax
  195.         jmp 0:.in_rm
  196.  
  197. .in_rm:                    ; Back in real mode
  198.         mov ax,cs        ; Set up sane segments
  199.         mov ds,ax
  200.         mov es,ax
  201.         mov fs,ax
  202.         mov gs,ax
  203.         lss sp,[SavedSSSP]    ; Restore stack
  204.         jmp bx            ; Go to whereever we need to go...
  205.  
  206. com32_done:
  207.         call disable_a20
  208.         sti
  209.         jmp enter_command
  210.  
  211. ;
  212. ; 16-bit support code
  213. ;
  214.         bits 16
  215.  
  216. ;
  217. ; 16-bit interrupt-handling code
  218. ;
  219. com32_int_rm:
  220.         pushf                ; Flags on stack
  221.         push cs                ; Return segment
  222.         push word .cont            ; Return address
  223.         push dword edx            ; Segment:offset of IVT entry
  224.         retf                ; Invoke IVT routine
  225. .cont:        ; ... on resume ...
  226.         mov ebx,com32_int_resume
  227.         jmp com32_enter_pm        ; Go back to PM
  228.  
  229. ;
  230. ; 16-bit system call handling code
  231. ;
  232. com32_sys_rm:
  233.         pop gs
  234.         pop fs
  235.         pop es
  236.         pop ds
  237.         popad
  238.         popfd
  239.         mov [cs:Com32SysSP],sp
  240.         retf                ; Invoke routine
  241. .return:
  242.         ; We clean up SP here because we don't know if the
  243.         ; routine returned with RET, RETF or IRET
  244.         mov sp,[cs:Com32SysSP]
  245.         pushfd
  246.         pushad
  247.         push ds
  248.         push es
  249.         push fs
  250.         push gs
  251.         mov ebx,com32_sys_resume
  252.         jmp com32_enter_pm
  253.  
  254. ;
  255. ; 32-bit support code
  256. ;
  257.         bits 32
  258.  
  259. ;
  260. ; This is invoked on getting an interrupt in protected mode.  At
  261. ; this point, we need to context-switch to real mode and invoke
  262. ; the interrupt routine.
  263. ;
  264. ; When this gets invoked, the registers are saved on the stack and
  265. ; AL contains the register number.
  266. ;
  267. com32_handle_interrupt:
  268.         movzx eax,al
  269.         xor ebx,ebx        ; Actually makes the code smaller
  270.         mov edx,[ebx+eax*4]    ; Get the segment:offset of the routine
  271.         mov bx,com32_int_rm
  272.         jmp com32_enter_rm    ; Go to real mode
  273.  
  274. com32_int_resume:
  275.         popad
  276.         iret
  277.  
  278. ;
  279. ; Intcall/farcall invocation.  We manifest a structure on the real-mode stack,
  280. ; containing the com32sys_t structure from <com32.h> as well as
  281. ; the following entries (from low to high address):
  282. ; - Target offset
  283. ; - Target segment
  284. ; - Return offset
  285. ; - Return segment (== real mode cs == 0)
  286. ; - Return flags
  287. ;
  288. com32_farcall:
  289.         pushfd                ; Save IF among other things...
  290.         pushad                ; We only need to save some, but...
  291.  
  292.         mov eax,[esp+10*4]        ; CS:IP
  293.         jmp com32_syscall
  294.  
  295.  
  296. com32_intcall:
  297.         pushfd                ; Save IF among other things...
  298.         pushad                ; We only need to save some, but...
  299.  
  300.         movzx eax,byte [esp+10*4]    ; INT number
  301.         mov eax,[eax*4]            ; Get CS:IP from low memory
  302.  
  303. com32_syscall:
  304.         cld
  305.  
  306.         movzx edi,word [word SavedSSSP]
  307.         movzx ebx,word [word SavedSSSP+2]
  308.         sub edi,54        ; Allocate 54 bytes
  309.         mov [word SavedSSSP],di
  310.         shl ebx,4
  311.         add edi,ebx        ; Create linear address
  312.  
  313.         mov esi,[esp+11*4]    ; Source regs
  314.         xor ecx,ecx
  315.         mov cl,11        ; 44 bytes to copy
  316.         rep movsd
  317.  
  318.         ; EAX is already set up to be CS:IP
  319.         stosd            ; Save in stack frame
  320.         mov eax,com32_sys_rm.return    ; Return seg:offs
  321.         stosd            ; Save in stack frame
  322.         mov eax,[edi-12]    ; Return flags
  323.         and eax,0x200cd7    ; Mask (potentially) unsafe flags
  324.         mov [edi-12],eax    ; Primary flags entry
  325.         stosw            ; Return flags
  326.  
  327.         mov bx,com32_sys_rm
  328.         jmp com32_enter_rm    ; Go to real mode
  329.  
  330.         ; On return, the 44-byte return structure is on the
  331.         ; real-mode stack, plus the 10 additional bytes used
  332.         ; by the target address (see above.)
  333. com32_sys_resume:
  334.         movzx esi,word [word SavedSSSP]
  335.         movzx eax,word [word SavedSSSP+2]
  336.         mov edi,[esp+12*4]    ; Dest regs
  337.         shl eax,4
  338.         add esi,eax        ; Create linear address
  339.         and edi,edi        ; NULL pointer?
  340.         jnz .do_copy
  341. .no_copy:    mov edi,esi        ; Do a dummy copy-to-self
  342. .do_copy:    xor ecx,ecx
  343.         mov cl,11        ; 44 bytes
  344.         rep movsd        ; Copy register block
  345.  
  346.         add dword [word SavedSSSP],54    ; Remove from stack
  347.  
  348.         popad
  349.         popfd
  350.         ret            ; Return to 32-bit program
  351.  
  352.         bits 16
  353.  
  354.         section .bss
  355.         alignb 4
  356. PMESP        resd 1            ; Protected-mode ESP
  357. Com32SysSP    resw 1            ; SP saved during COM32 syscall
  358.  
  359.         section .text
  360.